package com.ywu.sentinel.sdk.config;

import com.ywu.common.gson.GsonUtils;
import com.ywu.sentinel.sdk.dto.*;
import com.ywu.sentinel.sdk.service.FlowRuleService;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.sql.*;

/**
 * @ClassName YwuFlowRuleSdkConfiguration
 * @Description TODO
 * @Author GroundDemo
 * @Date 2025/4/14 18:06
 * @Version 1.0
 **/
@Component
@Configuration
public class YwuFlowRuleSdkConfiguration implements EnvironmentAware {

    private Environment environment;

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @PostConstruct
    public void doLoadRules() {
        // 从环境中获取数据库连接信息
        String url = environment.getProperty("ywu.config.datasource.url");
        String user = environment.getProperty("ywu.config.datasource.user");
        String password = environment.getProperty("ywu.config.datasource.password");
        String driver = environment.getProperty("ywu.config.datasource.driver.class");
        String tenantId = environment.getProperty("com.ywu.tenantId");
        String appName = environment.getProperty("spring.application.name");
        try {
            Class.forName(driver);
            Connection connection = DriverManager.getConnection(url, user, password);
            // 加载流控规则
            loadFlowRule(connection, appName, tenantId);
            // 加载熔断规则
            loadBlowRule(connection, appName, tenantId);
            // 加载热点规则
            loadHotRule(connection, appName, tenantId);
            // 加载系统规则
            loadSystemRule(connection, appName, tenantId);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    /**
    * @Author GroundDemo
    * @Description 加载流控规则
    * @Date 22:31 2025/4/15
    * @Param [connection, appName, tenantId]
    * @return void
    **/
    private void loadFlowRule(Connection connection, String appName, String tenantId) throws SQLException {
        String flowSql = "SELECT * FROM ywu_sentinel_flow_rule WHERE app = ? AND tenant_id = ?";
        PreparedStatement statement = connection.prepareStatement(flowSql);
        statement.setString(1, appName);
        statement.setString(2, tenantId);
        ResultSet resultSet = statement.executeQuery();
        while (resultSet.next()) {
            String id = resultSet.getString("id");
            String app = resultSet.getString("app");
            int controlBehavior = resultSet.getInt("control_behavior");
            int count = resultSet.getInt("count");
            int grade = resultSet.getInt("grade");
            int maxQueueingTimeMs = resultSet.getInt("max_queueing_time_ms");
            int warmUpPeriodSec = resultSet.getInt("warm_up_period_sec");
            int strategy = resultSet.getInt("strategy");
            String refResource = resultSet.getString("ref_resource");
            String resource = resultSet.getString("resource");
            // 构建对象
            YwuFlowRuleDto ywuFlowRuleDto = new YwuFlowRuleDto();
            ywuFlowRuleDto.setId(id);
            ywuFlowRuleDto.setApp(app);
            ywuFlowRuleDto.setControlBehavior(controlBehavior);
            ywuFlowRuleDto.setCount(count);
            ywuFlowRuleDto.setGrade(grade);
            ywuFlowRuleDto.setMaxQueueingTimeMs(maxQueueingTimeMs);
            ywuFlowRuleDto.setWarmUpPeriodSec(warmUpPeriodSec);
            ywuFlowRuleDto.setStrategy(strategy);
            ywuFlowRuleDto.setRefResource(refResource);
            ywuFlowRuleDto.setResource(resource);
            FlowRuleService.loadFlowRules(ywuFlowRuleDto);
        }
        statement.close();
    }

    /**
    * @Author GroundDemo
    * @Description 加载熔断规则
    * @Date 22:31 2025/4/15
    * @Param [connection, appName, tenantId]
    * @return void
    **/
    private void loadBlowRule(Connection connection, String appName, String tenantId) throws SQLException {
        String flowSql = "SELECT * FROM ywu_sentinel_blow_rule WHERE app = ? AND tenant_id = ?";
        PreparedStatement statement = connection.prepareStatement(flowSql);
        statement.setString(1, appName);
        statement.setString(2, tenantId);
        ResultSet resultSet = statement.executeQuery();
        while (resultSet.next()) {
            String id = resultSet.getString("id");
            String app = resultSet.getString("app");
            int grade = resultSet.getInt("grade");
            String resource = resultSet.getString("resource");
            int minRequestAmount = resultSet.getInt("min_request_amount");
            int statIntervalMs = resultSet.getInt("stat_interval_ms");
            double count = resultSet.getDouble("count");
            int timeWindow = resultSet.getInt("time_window");
            double slowRatioThreshold = resultSet.getDouble("slow_ratio_threshold");
            // 构建对象
            YwuBlowRuleDto ywuBlowRuleDto = new YwuBlowRuleDto();
            ywuBlowRuleDto.setId(id);
            ywuBlowRuleDto.setApp(app);
            ywuBlowRuleDto.setGrade(grade);
            ywuBlowRuleDto.setResource(resource);
            ywuBlowRuleDto.setMinRequestAmount(minRequestAmount);
            ywuBlowRuleDto.setStatIntervalMs(statIntervalMs);
            ywuBlowRuleDto.setCount(count);
            ywuBlowRuleDto.setTimeWindow(timeWindow);
            ywuBlowRuleDto.setSlowRatioThreshold(slowRatioThreshold);
            FlowRuleService.loadDegradeRules(ywuBlowRuleDto);
        }
        statement.close();
    }

    /**
    * @Author GroundDemo
    * @Description 加载热点规则
    * @Date 22:36 2025/4/15
    * @Param [connection, appName, tenantId]
    * @return void
    **/
    private void loadHotRule(Connection connection, String appName, String tenantId) throws SQLException {
        String flowSql = "SELECT * FROM ywu_sentinel_hot_rule WHERE app = ? AND tenant_id = ?";
        PreparedStatement statement = connection.prepareStatement(flowSql);
        statement.setString(1, appName);
        statement.setString(2, tenantId);
        ResultSet resultSet = statement.executeQuery();
        while (resultSet.next()) {
            String id = resultSet.getString("id");
            String app = resultSet.getString("app");
            String resource = resultSet.getString("resource");
            int count = resultSet.getInt("count");
            int durationInSec = resultSet.getInt("duration_in_sec");
            int paramIdx = resultSet.getInt("param_idx");
            int grade = resultSet.getInt("grade");
            String paramFlowItemList = resultSet.getString("param_flow_item_list");
            // 构建对象
            YwuHotRuleDto ywuHotRuleDto = new YwuHotRuleDto();
            ywuHotRuleDto.setId(id);
            ywuHotRuleDto.setApp(app);
            ywuHotRuleDto.setResource(resource);
            ywuHotRuleDto.setCount(count);
            ywuHotRuleDto.setDurationInSec(durationInSec);
            ywuHotRuleDto.setParamIdx(paramIdx);
            ywuHotRuleDto.setGrade(grade);
            ywuHotRuleDto.setParamFlowItemList(GsonUtils.deserializeList(paramFlowItemList, YwuParamItemDto.class));
            FlowRuleService.loadHotRules(ywuHotRuleDto);
        }
        statement.close();
    }

    /**
    * @Author GroundDemo
    * @Description 加载系统规则
    * @Date 22:43 2025/4/15
    * @Param [connection, appName, tenantId]
    * @return void
    **/
    private void loadSystemRule(Connection connection, String appName, String tenantId) throws SQLException {
        String flowSql = "SELECT * FROM ywu_sentinel_system_rule WHERE app = ? AND tenant_id = ?";
        PreparedStatement statement = connection.prepareStatement(flowSql);
        statement.setString(1, appName);
        statement.setString(2, tenantId);
        ResultSet resultSet = statement.executeQuery();
        while (resultSet.next()) {
            String id = resultSet.getString("id");
            String app = resultSet.getString("app");
            String type = resultSet.getString("type");
            int avgRt = resultSet.getInt("avg_rt");
            int highestSystemLoad = resultSet.getInt("highest_system_load");
            int maxThread = resultSet.getInt("max_thread");
            int qps = resultSet.getInt("qps");
            double highestCpuUsage = resultSet.getDouble("highest_cpu_usage");
            // 构建对象
            YwuSystemRuleDto ywuSystemRuleDto = new YwuSystemRuleDto();
            ywuSystemRuleDto.setId(id);
            ywuSystemRuleDto.setApp(app);
            ywuSystemRuleDto.setType(type);
            ywuSystemRuleDto.setAvgRt(avgRt);
            ywuSystemRuleDto.setHighestSystemLoad(highestSystemLoad);
            ywuSystemRuleDto.setMaxThread(maxThread);
            ywuSystemRuleDto.setQps(qps);
            ywuSystemRuleDto.setHighestCpuUsage(highestCpuUsage);
            FlowRuleService.loadSystemRules(ywuSystemRuleDto);
        }
    }
}
